package server;

import both.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.nio.file.*;
import javax.xml.bind.*;

public class ProfileTab extends JPanel implements ActionListener {

    private String fileFolder;
    private JButton timeDisplay, valueDisplay;
    private int time, value;
    private int screenWidth = (int) Game.width;
    private int screenHeight = (int) Game.height;
    private JTextField serverLoc, clientLoc, questionLoc;
    private final GameShowServer server;
    // static variables to avoid typo errors
    private static final String INCREASETIME = "1";
    private static final String DECREASETIME = "2";
    private static final String INCREASEVALUE = "3";
    private static final String DECREASEVALUE = "4";
    private static final String SERVEROUTPUT = "5";
    private static final String CLIENTOUTPUT = "6";
    private static final String QUESTIONFILE = "7";
    private File defaultSelected;
    private static final int textWidth = 300;

    ProfileTab(GameShowServer server) {
        super();
        this.server = server;
        time = 30;
        value = 10;
        add(getTimePanel());
        add(getValuePanel());
        add(getServerOutputPanel());
        add(getClientOutputPanel());
        add(getQuestionFilePanel());
        URL url = getClass().getClassLoader().getResource("files.xml");
        String urlString = url.getPath();
        int index = urlString.indexOf("build/classes/files.xml");
        try {
            fileFolder = urlString.substring(0, index) + "src/resources/files.xml";
        } catch (Exception ex) {
        }
        try {
            setOutputFolders();
        } catch (JAXBException e) {
            xmlWindow(e);
        }
        setSize(screenWidth / 16, screenHeight / 9);
        setLayout(new GridLayout(0, 1, 10, 30));
        setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
        

    }

    private void setOutputFolders() throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(DefaultFiles.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        File XMLfile = new File(fileFolder);
        DefaultFiles files = (DefaultFiles) jaxbUnmarshaller.unmarshal(XMLfile);
        if (serverLoc == null) {
            serverLoc = new JTextField();
        }
        serverLoc.setText(files.getServerOutput());
        if (clientLoc == null) {
            clientLoc = new JTextField();
        }
        clientLoc.setText(files.getClientOutput());
        server.setServerOutputFolder(serverLoc.getText());
        server.setClientOutputFolder(clientLoc.getText());
    }

    private void xmlWindow(Exception e) {
        JFrame stackFrame = new JFrame("XML Error");
        stackFrame.setBounds(300, 200, 700, 330);
        StackTraceElement[] stackTrace = e.getStackTrace();
        String traceText = new String(e.toString());
        for (StackTraceElement s : stackTrace) {
            traceText = traceText + "\n" + s.toString();
        }
        JTextArea textArea = new JTextArea(traceText);
        textArea.setEditable(false);
        textArea.setSelectedTextColor(Color.RED);
        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setPreferredSize(new Dimension(700, 330));
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        JPanel contentPane = new JPanel();
        contentPane.add(scrollPane);
        stackFrame.setContentPane(contentPane);
        stackFrame.pack();
        stackFrame.setVisible(true);
    }

    private JPanel getTimePanel() {

        // panel
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel jl1 = new JLabel(StringFormatter.formatString("Default Question Time:", StringFormatter.QUESTION_STR, textWidth));
        panel.add(jl1);

        // display
        JPanel timeBox = new JPanel();
        timeBox.setLayout(new GridLayout(1, 3, 0, 0));
        timeDisplay = new JButton(StringFormatter.formatString(time + " seconds",StringFormatter.ANSWER_STR, textWidth / 3));
        timeDisplay.setEnabled(false);
        timeDisplay.setBackground(Color.WHITE);
        timeBox.add(timeDisplay);

        // up and down buttons
        JPanel buttonBox = new JPanel();
        buttonBox.setLayout(new GridLayout(2, 0, 0, 0));
        JButton increaseTime = new JButton(StringFormatter.formatString("^", StringFormatter.QUESTION_STR, textWidth / 36)); // will be changed
        increaseTime.setActionCommand(INCREASETIME);
        increaseTime.addActionListener(this);
        buttonBox.add(increaseTime);
        JButton decreaseTime = new JButton(StringFormatter.formatString("v", StringFormatter.ANSWER_STR, textWidth / 36)); // will be changed
        decreaseTime.setActionCommand(DECREASETIME);
        decreaseTime.addActionListener(this);
        buttonBox.add(decreaseTime);
        timeBox.add(buttonBox);
        panel.add(timeBox);
        return panel;

    }

    private JPanel getValuePanel() {

        // panel
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel jl1 = new JLabel(StringFormatter.formatString("Default Question Value:", StringFormatter.QUESTION_STR, textWidth));
        panel.add(jl1);

        // display
        JPanel valueBox = new JPanel();
        valueBox.setLayout(new GridLayout(1, 0, 0, 0));
        valueDisplay = new JButton(StringFormatter.formatString(value + " points",StringFormatter.ANSWER_STR, textWidth / 3));
        valueDisplay.setEnabled(false);
        valueDisplay.setBackground(Color.WHITE);
        valueBox.add(valueDisplay);

        // up and down buttons
        JPanel buttonBox = new JPanel();
        buttonBox.setLayout(new GridLayout(2, 0, 0, 0));
        JButton increaseValue = new JButton(StringFormatter.formatString("^", StringFormatter.QUESTION_STR, textWidth / 36)); // will be changed
        increaseValue.setActionCommand(INCREASEVALUE);
        increaseValue.addActionListener(this);
        buttonBox.add(increaseValue);
        JButton decreaseValue = new JButton(StringFormatter.formatString("v", StringFormatter.ANSWER_STR, textWidth / 36)); // will be changed
        decreaseValue.setActionCommand(DECREASEVALUE);
        decreaseValue.addActionListener(this);
        buttonBox.add(decreaseValue);
        valueBox.add(buttonBox);
        panel.add(valueBox);
        return panel;

    }

    private JPanel getServerOutputPanel() {

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel jl1 = new JLabel(StringFormatter.formatString("Server Output Folder:", StringFormatter.QUESTION_STR, textWidth));
        panel.add(jl1);
        serverLoc = new JTextField(25);
        serverLoc.setBackground(Color.WHITE);
        //serverLoc.setEnabled(false);
        panel.add(serverLoc);
        JButton browse = new JButton(StringFormatter.formatString("Browse...", StringFormatter.ANSWER_STR, textWidth / 5)); // will be changed
        browse.setActionCommand(SERVEROUTPUT);
        browse.addActionListener(this);
        panel.add(browse);
        return panel;
    }

    private JPanel getClientOutputPanel() {

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel jl1 = new JLabel(StringFormatter.formatString("Client Output Folder:", StringFormatter.QUESTION_STR, textWidth));
        panel.add(jl1);
        clientLoc = new JTextField(25);
        clientLoc.setBackground(Color.WHITE);
        //clientLoc.setEnabled(false);
        panel.add(clientLoc);
        JButton browse = new JButton(StringFormatter.formatString("Browse...", StringFormatter.ANSWER_STR, textWidth / 5)); // will be changed
        browse.setActionCommand(CLIENTOUTPUT);
        browse.addActionListener(this);
        panel.add(browse);
        return panel;

    }

    private JPanel getQuestionFilePanel() {

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel jl1 = new JLabel(StringFormatter.formatString("Question File:", StringFormatter.QUESTION_STR, textWidth));
        panel.add(jl1);
        questionLoc = new JTextField(25);
        questionLoc.setBackground(Color.WHITE);
        questionLoc.setEnabled(true);
        panel.add(questionLoc);
        JButton browse = new JButton(StringFormatter.formatString("Browse...", StringFormatter.ANSWER_STR, textWidth / 5)); // will be changed
        browse.setActionCommand(QUESTIONFILE);
        browse.addActionListener(this);
        panel.add(browse);
        return panel;
    }

    public boolean optionsValid() {
        boolean serverComplete = !serverLoc.getText().equals("");
        boolean clientComplete = !clientLoc.getText().equals("");
        boolean questionComplete = !questionLoc.getText().equals("");
        if (serverComplete && clientComplete && questionComplete) {
            sendLocations();
            return true;
        } else {
            return false;
        }
    }

    public void sendLocations() {
        try {
            server.setServerOutputFolder(serverLoc.getText());
            server.setClientOutputFolder(clientLoc.getText());
            server.setQuestionFile(questionLoc.getText());
            Game.setDefaultTime(time);
            Game.setDefaultPointValue(value);
        } catch (Exception e) {
            xmlWindow(e);
        }
    }

    public void createXml() throws JAXBException {
        DefaultFiles files = new DefaultFiles();
        files.setServerOutput(serverLoc.getText());
        files.setClientOutput(clientLoc.getText());
        JAXBContext jaxbContext = JAXBContext.newInstance(DefaultFiles.class);
        Marshaller jaxbMarshall = jaxbContext.createMarshaller();
        File tgfile = new File(fileFolder);
        jaxbMarshall.marshal(files, tgfile);
    }

    @Override
    public void actionPerformed(ActionEvent event) {

        String eventName = event.getActionCommand();
        switch (eventName) {
            case INCREASETIME:
                if (time < 999) {
                    time++;
                }
                timeDisplay.setText(StringFormatter.formatString(time + " seconds", StringFormatter.ANSWER_STR, textWidth / 3));
                Game.setDefaultTime(time);
                break;
            case DECREASETIME:
                if (time > 1) {
                    time--;
                }
                timeDisplay.setText(StringFormatter.formatString(time + " seconds", StringFormatter.ANSWER_STR, textWidth / 3));
                Game.setDefaultTime(time);
                break;
            case INCREASEVALUE:
                if (value < 999) {
                    value++;
                }
                valueDisplay.setText(StringFormatter.formatString(value + " points", StringFormatter.ANSWER_STR, textWidth / 3));
                Game.setDefaultPointValue(value);
                break;
            case DECREASEVALUE:
                if (value > 1) {
                    value--;
                }
                valueDisplay.setText(StringFormatter.formatString(value + " points", StringFormatter.ANSWER_STR, textWidth / 3));
                Game.setDefaultPointValue(value);
                break;
            case SERVEROUTPUT: {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                if (!(defaultSelected == null)) {
                    chooser.setCurrentDirectory(defaultSelected.getParentFile());
                }
                int returnVal = chooser.showOpenDialog(getParent());
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    defaultSelected = chooser.getSelectedFile();
                    serverLoc.setText(chooser.getSelectedFile().toString());
                    server.setServerOutputFolder(serverLoc.getText());
                } else if (returnVal == JFileChooser.CANCEL_OPTION) {
                    server.setServerOutputFolder(serverLoc.getText());
                }
//                try {
//                    createXml();
//                } catch (JAXBException ex) {
//                    xmlWindow(ex);
//                }
                break;
            }
            case CLIENTOUTPUT: {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                if (!(defaultSelected == null)) {
                    chooser.setCurrentDirectory(defaultSelected.getParentFile());
                }
                int returnVal = chooser.showOpenDialog(getParent());
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    defaultSelected = chooser.getSelectedFile();
                    clientLoc.setText(chooser.getSelectedFile().toString());
                    server.setClientOutputFolder(clientLoc.getText());
                } else if (returnVal == JFileChooser.CANCEL_OPTION) {
                    server.setClientOutputFolder(serverLoc.getText());
                }
//                try {
//                    createXml();
//                } catch (JAXBException ex) {
//                    xmlWindow(ex);
//                }
                break;
            }
            case QUESTIONFILE: {
                JFileChooser chooser = new JFileChooser();
                if (!(defaultSelected == null)) {
                    chooser.setCurrentDirectory(defaultSelected.getParentFile());
                }
                int returnVal = chooser.showOpenDialog(getParent());
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    defaultSelected = chooser.getSelectedFile();
                    questionLoc.setText(chooser.getSelectedFile().toString());
                    try {
                        server.setQuestionFile(questionLoc.getText());
                    } catch (Exception e) {
                        xmlWindow(e);
                    }
                }
                break;
            }
        }

    }
}
